#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <functional>
#include <string>
#include <thread>
using namespace std;

//void fun(int a,int b)
//{
//	cout << a << " ";
//	cout << b << endl;
//}

//bind交换参数位置
//int main()
//{
//	using namespace std::placeholders;
//	function<void(int, int)> f1 = fun;
//	function<void(int, int)> f2 = bind(fun, _2, _1); //_1和_2都是占位符号，表示第几个参数 通过占位符 调整参数位置
//	f1(1, 2);
//	f2(1, 2);
//	return 0;
//}

//struct fun
//{
//	fun(int n) :num(n) {}
//	int operator()(int a, int b) { return (a + b) * num; }
//private:
//	int num;
//};
//
////bind改变参数个数
//int main()
//{
//	using namespace std::placeholders;
//
//	//我们在直接调用fun时需要初始化num
//	cout << fun(2)(3, 4) << endl;
//
//	//auto f2 = bind(&fun::operator(), fun(2), _1, _2);;
//	//如果第一个参数绑死了 那么下一个参数仍然是_1 _2 ...
//	//fun(this, int, int); 函数参数
//	function<int(int, int)> f2 = bind(&fun::operator(), fun(2), _1, _2); //我们可以提前初始化好num 
//	cout<< f2(3, 4) << endl;
//
//	function<int(int)> f3 = bind(&fun::operator(), fun(2), 10, _1); //当然也可以这样写
//	cout << f3(2) << endl;
//	return 0;
//}


// 两次捕捉异常 就近捕捉 异常重新抛出
double divis(double a, double b) 
{ 
	if (b == 0)
		throw "除零错误！\n"; //除数为0则 抛异常让调用函数捕捉
	else
		return a / b; 
}

void fun(double a, double b) noexcept //noexcept标记后 如果抛异常则会报错
{
	//if (b == 0)
	//	throw "除零错误！\n"; //除数为0则 抛异常让调用函数捕捉
	//else
	//	cout << divis(a, b) << endl;
	int* arr = new int[10];
	//try //对于两次异常捕捉，会选择最近的一个调用函数捕捉异常
	//{
		cout << divis(a, b) << endl; //noexcept 一旦碰到异常 就算自己不捕捉 也会断言终止程序
	//}
	//catch (const char* s)
	////catch (char s) //如果类型不匹配 则会去外层继续捕捉
	//{
	//	//cout << s << endl;
	//	cout << "delete[]" << arr << endl;
	//	delete[] arr; //如果直接在main函数中捕获异常会造成内存泄漏
	//	throw s; //重新抛出 在释放内存后继续抛出异常
	//}
	//catch (...) //捕捉任意异常
	//{
	//	cout << "delete[]" << arr << endl;
	//	delete[] arr; //如果直接在main函数中捕获异常会造成内存泄漏
	//	throw; //重写抛出 捕到什么抛什么
	//}

	cout << "delete[]" << arr << endl;
	delete[] arr;

}

int main()
{
	try
	{
		fun(1, 0);
	}
	catch (const char* s)
	{
		cout << s << endl;
	}

	return 0;
}



//采用对象的方式抛异常
//class Exception
//{
//public:
//	Exception(int errid, const string& errmsg)
//		:_errid(errid)
//		, _errmsg(errmsg)
//	{}
//
//	int geterrid() const { return _errid; }
//	virtual string what() const
//	{
//		return _errmsg;
//	}
//
//protected:
//	int _errid; //错误码
//	string _errmsg;
//};

//double divis(double a, double b) 
//{ 
//	if (b == 0)
//		throw Exception(1,"除零错误！\n"); //除数为0则 抛异常让调用函数捕捉
//	else
//		return a / b; 
//}


//int main()
//{
//	try
//	{
//		divis(1, 0);
//	}
//	catch (const Exception& e)
//	{
//		cout << e._errmsg << endl;
//	}
//
//	return 0;
//}

//class sqlException:public Exception
//{
//public:
//	sqlException(int errid, const string& errmsg, const string& sql_type)
//		:Exception(errid, errmsg)
//		, sqltype(sql_type)
//	{}
//
//	virtual string what() const
//	{
//		return "sqlException:" + _errmsg + "->" + sqltype;
//	}
//
//private:
//	string sqltype;
//};
//
//
//class cacheException :public Exception
//{
//public:
//	cacheException(int errid, const string& errmsg)
//		:Exception(errid, errmsg)
//	{}
//
//	virtual string what() const
//	{
//		return "cacheException:" + _errmsg;
//	}
//};
//
//class httpException :public Exception
//{
//public:
//	httpException(int errid, const string& errmsg, const string& http_type)
//		:Exception(errid, errmsg)
//		, httptype(http_type)
//	{}
//
//	virtual string what() const
//	{
//		return "httpException:" + _errmsg + "->" + httptype;
//	}
//private:
//	string httptype;
//};
//
//void SQLMgr()
//{
//	srand(time(0));
//	if (rand() % 7 == 0)
//	{
//		throw sqlException(100, "权限不足", "select * from name = '张三'");
//	}
//
//	cout << "调用成功" << endl;
//}
//
//void CacheMgr()
//{
//	srand(time(0));
//	if (rand() % 5 == 0)
//	{
//		throw cacheException(100,"权限不足");
//	}
//	else if (rand() % 6 == 0)
//	{
//		throw cacheException(101,"数据不存在");
//	}
//
//	SQLMgr();
//}
//
//void HttpServer()
//{
//	// 模拟服务出错
//	srand(time(0));
//	if (rand() % 3 == 0)
//	{
//		throw httpException(100, "请求资源不存在",  "get");
//	}
//	else if (rand() % 4 == 0)
//	{
//		throw httpException(101, "权限不足",  "post");
//	}
//
//	CacheMgr();
//}
//
//int main()
//{
//	while (1)
//	{
//		this_thread::sleep_for(chrono::seconds(1));
//
//		try
//		{
//			HttpServer();
//		}
//		catch (const Exception& e) // 这里捕获父类对象就可以
//		{
//			// 多态
//			cout << e.what() << endl;
//		}
//		catch (...) //捕捉任意异常 当没有符合异常捕捉的条件时 该catch捕捉任意异常表示未知异常
//		{
//			cout << "未知异常！" << endl;
//		}
//	}
//
//	return 0;
//}